gl renderer: Use a GArray for the shadow cache
authorTimm Bäder <mail@baedert.org>
Sun, 15 Jul 2018 05:23:18 +0000 (07:23 +0200)
committerTimm Bäder <mail@baedert.org>
Tue, 17 Jul 2018 15:33:46 +0000 (17:33 +0200)
It's very small usually, in default Adwaita the only blurred outset
shadow we have is the one for the CSD'd toplevel window.

gsk/gl/gskglshadowcache.c
gsk/gl/gskglshadowcacheprivate.h

index 8d8960e88ba916f678503c559aff393811ea54a3..8c1f68c5a10bef5afa27feddeb9d264687838e78 100644 (file)
@@ -9,9 +9,12 @@ typedef struct
 
 typedef struct
 {
+  GskRoundedRect outline;
+  float blur_radius;
+
   int texture_id;
   guint used : 1;
-} CacheValue;
+} CacheItem;
 
 static gboolean
 key_equal (const void *x,
@@ -20,21 +23,34 @@ key_equal (const void *x,
   const CacheKey *a = x;
   const CacheKey *b = y;
 
-  return memcmp (&a->outline, &b->outline, sizeof (GskRoundedRect)) == 0 &&
+  return graphene_size_equal (&a->outline.corner[0], &b->outline.corner[0]) &&
+         graphene_size_equal (&a->outline.corner[1], &b->outline.corner[1]) &&
+         graphene_size_equal (&a->outline.corner[2], &b->outline.corner[2]) &&
+         graphene_size_equal (&a->outline.corner[3], &b->outline.corner[3]) &&
+         graphene_rect_equal (&a->outline.bounds, &b->outline.bounds) &&
          a->blur_radius == b->blur_radius;
 }
 
 void
 gsk_gl_shadow_cache_init (GskGLShadowCache *self)
 {
-  self->textures = g_hash_table_new_full (g_direct_hash, key_equal, g_free, g_free);
+  self->textures = g_array_new (FALSE, TRUE, sizeof (CacheItem));
 }
 
 void
 gsk_gl_shadow_cache_free (GskGLShadowCache *self,
                           GskGLDriver      *gl_driver)
 {
-  g_hash_table_unref (self->textures);
+  guint i, p;
+
+  for (i = 0, p = self->textures->len; i < p; i ++)
+    {
+      const CacheItem *item = &g_array_index (self->textures, CacheItem, i);
+
+      gsk_gl_driver_destroy_texture (gl_driver, item->texture_id);
+    }
+
+  g_array_free (self->textures, TRUE);
   self->textures = NULL;
 }
 
@@ -42,26 +58,25 @@ void
 gsk_gl_shadow_cache_begin_frame (GskGLShadowCache *self,
                                  GskGLDriver      *gl_driver)
 {
-  GHashTableIter iter;
-  CacheKey *key;
-  CacheValue *value;
+  guint i, p;
 
   /* We remove all textures with used = FALSE since those have not been used in the
    * last frame. For all others, we reset the `used` value to FALSE instead and see
    * if they end up with TRUE in the next call to begin_frame. */
-
-  g_hash_table_iter_init (&iter, self->textures);
-  while (g_hash_table_iter_next (&iter, (gpointer *)&key, (gpointer *)&value))
+  for (i = 0, p = self->textures->len; i < p; i ++)
     {
-      if (!value->used)
+      CacheItem *item = &g_array_index (self->textures, CacheItem, i);
+
+      if (!item->used)
         {
-          /* Remove */
-          gsk_gl_driver_destroy_texture (gl_driver, value->texture_id);
-          g_hash_table_iter_remove (&iter);
+          gsk_gl_driver_destroy_texture (gl_driver, item->texture_id);
+          g_array_remove_index_fast (self->textures, i);
+          p --;
+          i --;
         }
       else
         {
-          value->used = FALSE;
+          item->used = FALSE;
         }
     }
 }
@@ -76,24 +91,33 @@ gsk_gl_shadow_cache_get_texture_id (GskGLShadowCache     *self,
                                     const GskRoundedRect *shadow_rect,
                                     float                 blur_radius)
 {
-  CacheValue *value;
+  CacheItem *item= NULL;
+  guint i;
 
   g_assert (self != NULL);
   g_assert (gl_driver != NULL);
   g_assert (shadow_rect != NULL);
 
-  value = g_hash_table_lookup (self->textures,
-                               &(CacheKey){
-                                 *shadow_rect,
-                                 blur_radius
-                               });
+  for (i = 0; i < self->textures->len; i ++)
+    {
+      CacheItem *k = &g_array_index (self->textures, CacheItem, i);
+
+      if (key_equal (&(CacheKey){*shadow_rect, blur_radius},
+                     &(CacheKey){k->outline, k->blur_radius}))
+        {
+          item = k;
+          break;
+        }
+    }
 
-  if (value == NULL)
+  if (item == NULL)
     return 0;
 
-  value->used = TRUE;
+  item->used = TRUE;
 
-  return value->texture_id;
+  g_assert (item->texture_id != 0);
+
+  return item->texture_id;
 }
 
 void
@@ -102,20 +126,17 @@ gsk_gl_shadow_cache_commit (GskGLShadowCache     *self,
                             float                 blur_radius,
                             int                   texture_id)
 {
-  CacheKey *key;
-  CacheValue *value;
+  CacheItem *item;
 
   g_assert (self != NULL);
   g_assert (shadow_rect != NULL);
   g_assert (texture_id > 0);
 
-  key = g_new0 (CacheKey, 1);
-  key->outline = *shadow_rect;
-  key->blur_radius = blur_radius;
-
-  value = g_new0 (CacheValue, 1);
-  value->used = TRUE;
-  value->texture_id = texture_id;
+  g_array_set_size (self->textures, self->textures->len + 1);
+  item = &g_array_index (self->textures, CacheItem, self->textures->len - 1);
 
-  g_hash_table_insert (self->textures, key, value);
+  item->outline = *shadow_rect;
+  item->blur_radius = blur_radius;
+  item->used = TRUE;
+  item->texture_id = texture_id;
 }
index e4f4814f21dc15edd7aeadce99b15e0cd362e2d7..6623f1623595ec3c7c3be6379177b912b43d5259 100644 (file)
@@ -9,7 +9,7 @@
 
 typedef struct
 {
-  GHashTable *textures;
+  GArray *textures;
 } GskGLShadowCache;